﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpSvn;
using GestoreSuperProgetto.Model;

namespace GestoreSuperProgetto
{
    public partial class LabelManagment : Form
    {
        public class internalLabelSPrj
        {
            public long LABEL_ID { get; set; }
            public long SPRJ_ID { get; set; }

            public string LABEL_NAME { get; set; }
            public string SPRJ_NAME { get; set; }
        }

        private SvnClient _client;
        public LabelManagment(SvnClient client)
            : this()
        {
            _client = client;
        }

        public LabelManagment()
        {
            InitializeComponent();
        }

        private void dateChk_CheckedChanged(object sender, EventArgs e)
        {
            datePicker.Enabled = dateChk.Checked;
        }

        private void startBtn_Click(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            string labelName = labelTxt.Text;

            if (labelTxt.MaskCompleted)
            {
                //var exist = (from lblSPrj in sPrj.LABEL_SUPERPROJECTS.CreateSourceQuery().Include("LABEL")
                //             where lblSPrj.LABEL.NAME.ToLower() == labelName.ToLower()
                //             select lblSPrj).Count();

                var exist = (from lbl in man.LABELS
                             where lbl.NAME.ToLower() == labelName.ToLower()
                             select lbl).Count();

                if(exist>0)
                {
                    MessageBox.Show(this, "Il nome dell'etichetta è già esistente", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else{

                    bool crash = false;
                    try
                    {
                        man.AddToLABELS(newLabel);
                        man.AddToLABEL_SUPERPROJECTS(newlblSPrj);

                        newlblSPrj.LABEL.NAME = labelName;
                        //newlblSPrj.LABEL.URL = "tags/" + labelName;

                        LABEL_SUPERPROJECTS sPrj = (labelPrjCmb.SelectedItem as LABEL_SUPERPROJECTS);

                        var list = newlblSPrj.LABEL_SUPERPROJECTS_CHILD.ToList();
                        newlblSPrj.LABEL_SUPERPROJECTS_CHILD.Clear();

                        foreach(var item in list)
                            newlblSPrj.LABEL_SUPERPROJECTS_CHILD.Add(
                                    (from lblsprj in man.LABEL_SUPERPROJECTS 
                                     where lblsprj.ID_LABEL == item.CurrentLabelID && 
                                     lblsprj.ID_SUPERPROJECT == item.ID_SUPERPROJECT 
                                     select lblsprj).First()
                                );
                        
                        var list2 = (from lproj in sPrj.LABEL_PROJECTS.CreateSourceQuery().Include("LABEL").Include("PROJECT")
                                     select lproj);

                        foreach (var lbl_prj in list2)
                        {
                            // Se è cambiato il superprogetto ho finito di gestire il precedente
                            var newChildlblPrj = new LABEL_PROJECTS()
                            {
                                LABEL = newLabel,
                                PROJECT = lbl_prj.PROJECT
                            };

                            if (MakeBranchAndTags(labelName, lbl_prj, newChildlblPrj))
                            {
                                man.AddToLABEL_PROJECTS(newChildlblPrj);

                                newlblSPrj.LABEL_PROJECTS.Add(newChildlblPrj);
                            }
                        }
                    }
                    catch(Exception ex) { crash = true;
                        MessageBox.Show(this, "Etichetta " + labelName + " non è stata creata! \n\n Error: "+ex.ToString(), "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    finally
                    {
                        if (!crash)
                        {
                            man.SaveChanges();
                            MessageBox.Show(this, "Etichetta " + labelName + " creata con successo!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                        }
                    }
                    
                    
                    Close();
                }
            }
            else
            {
                MessageBox.Show(this,"Il nome dell'etichetta non può essere vuoto", "",  MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private bool MakeBranchAndTags(string labelName, LABEL_PROJECTS targetlblPrj, LABEL_PROJECTS lblPrj)
        {
            bool createBranch = false;
            Uri destUri = new Uri(lblPrj.BranchFullUrl);

            try
            {
                SvnInfoEventArgs arg = null;
                _client.GetInfo(SvnTarget.FromUri(destUri), out arg);
            }
            catch
            {
                createBranch = true;
            }

            SvnTarget target = SvnTarget.FromUri(new Uri(targetlblPrj.BranchFullUrl));
            SvnCopyArgs copyArgs = new SvnCopyArgs();

            if (createBranch)
            {
                copyArgs.LogMessage = "Make " + labelName + " branch";

                if (dateChk.Checked)
                    copyArgs.Revision = new SvnRevision(datePicker.Value);
                else if (revChk.Checked)
                    copyArgs.Revision = new SvnRevision(long.Parse(revTxt.Text));

                copyArgs.CreateParents = true;

                if (!_client.RemoteCopy(target, destUri, copyArgs))
                {
                    return false;
                }
            }

            copyArgs = new SvnCopyArgs();
            destUri = new Uri(lblPrj.TagFullUrl);

            copyArgs.LogMessage = "Make " + labelName + " tag";
            
            if (!_client.RemoteCopy(target, destUri, copyArgs))
            {
                return false;
            }

            return true;
        }

        private void LabelManagment_Load(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            var SPrjs = (from sprj in man.SUPERPROJECTS
                         orderby sprj.NAME
                         select sprj).ToList();

            if (man.ActiveUser.ISADMIN != 1)
                SPrjs = SPrjs.Where(ele => man.ActiveUser.CheckPermission(ele.ID, TypePermission.Admin)).ToList();

            superProjCmb.DataSource = SPrjs;
        }

        private void superProjCmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            SUPERPROJECT sPrj = (superProjCmb.SelectedItem as SUPERPROJECT);

            var lblSPrjs = (from lblSPrj in man.LABEL_SUPERPROJECTS
                            where lblSPrj.ID_SUPERPROJECT == sPrj.ID
                            select lblSPrj).ToList();

            labelPrjCmb.DataSource = lblSPrjs;
        }

        private void cancelBtn_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void deleteBtn_Click(object sender, EventArgs e)
        {
            var man = (Owner as StartForm).DataManager;

            LABEL_SUPERPROJECTS sPrj = (labelPrjCmb.SelectedItem as LABEL_SUPERPROJECTS);

            sPrj.LABEL_PROJECTS.Load();
            var list = (from label_sproj in sPrj.LABEL_SUPERPROJECTS_CHILD.CreateSourceQuery().Include("SUPERPROJECT").Include("LABEL_PROJECTS").Include("LABEL_PROJECTS.PROJECT")
                        from label_proj in label_sproj.LABEL_PROJECTS
                        orderby label_sproj.SUPERPROJECT.NAME
                        select new { Label_SuperProject = label_sproj, Label_Project = label_proj });

            foreach (var obj in list)
            {
                if (obj.Label_Project.RemoveFromSvn(_client))
                {
                    obj.Label_SuperProject.LABEL_PROJECTS.Remove(obj.Label_Project);
                    man.DeleteObject(obj.Label_Project);
                }
                man.DeleteObject(obj.Label_SuperProject);
                //CheckoutProject(defaultDir, obj.Label_SuperProject, obj.Label_Project, tagsRadio.Checked);
            }

            var list2 = (from lproj in sPrj.LABEL_PROJECTS.CreateSourceQuery().Include("LABEL").Include("PROJECT")
                         select lproj);

            foreach (var lbl_prj in list2)
            {
                if (lbl_prj.RemoveFromSvn(_client))
                {
                    sPrj.LABEL_PROJECTS.Remove(lbl_prj);
                    man.DeleteObject(lbl_prj);                
                }
            }

            var label = sPrj.LABEL;

            //label.LABEL_PROJECTS.Count

            man.DeleteObject(sPrj);

            if(label.LABEL_PROJECTS.Count() == 0 && label.LABEL_SUPERPROJECTS.Count() == 0)
                man.DeleteObject(label);

            man.SaveChanges();
        }

        private LABEL newLabel = null;
        private LABEL_SUPERPROJECTS newlblSPrj = null;

        private void createNewLabel()
        {
            LABEL_SUPERPROJECTS sPrj = (labelPrjCmb.SelectedItem as LABEL_SUPERPROJECTS);

            var man = (Owner as StartForm).DataManager;

            string labelName = labelTxt.Text;

            newLabel = new LABEL()
            {
                NAME = labelName,
                VERSION = 1,
            };

            newlblSPrj = new LABEL_SUPERPROJECTS()
            {
                LABEL = newLabel,
                SUPERPROJECT = sPrj.SUPERPROJECT
            };
        }

        
        private void labelPrjCmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            LABEL_SUPERPROJECTS sPrj = (labelPrjCmb.SelectedItem as LABEL_SUPERPROJECTS);
            deleteBtn.Enabled = !sPrj.LABEL.URL.Contains("trunk");
            if(deleteBtn.Enabled)
                labelTxt.Text = sPrj.LABEL.NAME;

            createNewLabel();
     
            sPrj.LABEL_PROJECTS.Load();
            var list = (from label_sproj in sPrj.LABEL_SUPERPROJECTS_CHILD.CreateSourceQuery().
                            Include("SUPERPROJECT").
                            Include("LABEL_PROJECTS").
                            Include("LABEL_PROJECTS.PROJECT")
                        orderby label_sproj.SUPERPROJECT.NAME
                        select label_sproj).ToList();

            foreach (var lsprj in list)
                newlblSPrj.LABEL_SUPERPROJECTS_CHILD.Add(lsprj);

            dependecyGridInitialize = true;
            dependecyGrid.DataSource = newlblSPrj.LABEL_SUPERPROJECTS_CHILD.ToList();
            dependecyGridInitialize = false;
        }

        private void revChk_CheckedChanged(object sender, EventArgs e)
        {
            revTxt.Enabled = revChk.Checked;
        }

        bool dependecyGridInitialize = false;
        private void dependecyGrid_SelectionChanged(object sender, EventArgs e)
        {
            if (dependecyGrid.SelectedCells.Count == 0)
                return;
            var rowindex = dependecyGrid.SelectedCells[0].RowIndex;

            var list = (dependecyGrid.DataSource as List<LABEL_SUPERPROJECTS>);

            var tag = list[rowindex];

            var labels = (from ele in tag.SUPERPROJECT.LABEL_SUPERPROJECTS
                          select ele.LABEL).ToList();

            (dependecyGrid[1, rowindex] as DataGridViewComboBoxCell).DisplayMember = "NAME";
            (dependecyGrid[1, rowindex] as DataGridViewComboBoxCell).ValueMember = "ID";
            (dependecyGrid[1, rowindex] as DataGridViewComboBoxCell).DataSource = labels;
        }
        
        private void dependecyGrid_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            var dgv = sender as DataGridView;
            if ( (dgv[e.ColumnIndex, e.RowIndex] as DataGridViewCell).EditType != null &&
                 (dgv[e.ColumnIndex, e.RowIndex] as DataGridViewCell).EditType.ToString() == "System.Windows.Forms.DataGridViewComboBoxEditingControl" )
                SendKeys.Send("{F4}");
            
        }
    }
}
